<!doctype html>



  


<html class="theme-next muse use-motion">
<head>
  <meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>



<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />












  
  
  <link href="/vendors/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css" />




  
  
  
  

  
    
    
  

  

  

  

  

  
    
    
    <link href="//fonts.googleapis.com/css?family=Lato:300,300italic,400,400italic,700,700italic&subset=latin,latin-ext" rel="stylesheet" type="text/css">
  






<link href="/vendors/font-awesome/css/font-awesome.min.css?v=4.4.0" rel="stylesheet" type="text/css" />

<link href="/css/main.css?v=5.0.1" rel="stylesheet" type="text/css" />


  <meta name="keywords" content="Hexo, NexT" />








  <link rel="shortcut icon" type="image/x-icon" href="/favicon.ico?v=5.0.1" />






<meta name="description" content="&amp;#x524D;&amp;#x8A00;YYModel&amp;#x5305;&amp;#x542B;&amp;#x4E86;&amp;#x5F88;&amp;#x591A;&amp;#x5E95;&amp;#x5C42;&amp;#x7684;&amp;#x77E5;&amp;#x8BC6;&amp;#xFF0C;&amp;#x5C06;&amp;#x5176;&amp;#x4E2D;&amp;#x7684;&amp;#x539F;&amp;#x7406;&amp;#x6478;&amp;#x900F;&amp;#xFF0C;&amp;#x5BF9;&amp;#x4E8E;&amp;">
<meta property="og:type" content="article">
<meta property="og:title" content="YYModel解析（2）">
<meta property="og:url" content="http://yoursite.com/2016/09/28/yymodel/index.html">
<meta property="og:site_name" content="Motom 的 秘密树屋">
<meta property="og:description" content="&amp;#x524D;&amp;#x8A00;YYModel&amp;#x5305;&amp;#x542B;&amp;#x4E86;&amp;#x5F88;&amp;#x591A;&amp;#x5E95;&amp;#x5C42;&amp;#x7684;&amp;#x77E5;&amp;#x8BC6;&amp;#xFF0C;&amp;#x5C06;&amp;#x5176;&amp;#x4E2D;&amp;#x7684;&amp;#x539F;&amp;#x7406;&amp;#x6478;&amp;#x900F;&amp;#xFF0C;&amp;#x5BF9;&amp;#x4E8E;&amp;">
<meta property="og:image" content="http://www.ianisme.com/wp-content/uploads/2016/01/objective-runtime-1.png">
<meta property="og:updated_time" content="2016-10-08T07:56:06.000Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="YYModel解析（2）">
<meta name="twitter:description" content="&amp;#x524D;&amp;#x8A00;YYModel&amp;#x5305;&amp;#x542B;&amp;#x4E86;&amp;#x5F88;&amp;#x591A;&amp;#x5E95;&amp;#x5C42;&amp;#x7684;&amp;#x77E5;&amp;#x8BC6;&amp;#xFF0C;&amp;#x5C06;&amp;#x5176;&amp;#x4E2D;&amp;#x7684;&amp;#x539F;&amp;#x7406;&amp;#x6478;&amp;#x900F;&amp;#xFF0C;&amp;#x5BF9;&amp;#x4E8E;&amp;">
<meta name="twitter:image" content="http://www.ianisme.com/wp-content/uploads/2016/01/objective-runtime-1.png">



<script type="text/javascript" id="hexo.configuration">
  var NexT = window.NexT || {};
  var CONFIG = {
    scheme: 'Muse',
    sidebar: {"position":"left","display":"post"},
    fancybox: true,
    motion: true,
    duoshuo: {
      userId: 0,
      author: '博主'
    }
  };
</script>




  <link rel="canonical" href="http://yoursite.com/2016/09/28/yymodel/"/>

  <title> YYModel解析（2） | Motom 的 秘密树屋 </title>
</head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans">

  










  
  
    
  

  <div class="container one-collumn sidebar-position-left page-post-detail ">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-meta ">
  

  <div class="custom-logo-site-title">
    <a href="/"  class="brand" rel="start">
      <span class="logo-line-before"><i></i></span>
      <span class="site-title">Motom 的 秘密树屋</span>
      <span class="logo-line-after"><i></i></span>
    </a>
  </div>
  <p class="site-subtitle"></p>
</div>

<div class="site-nav-toggle">
  <button>
    <span class="btn-bar"></span>
    <span class="btn-bar"></span>
    <span class="btn-bar"></span>
  </button>
</div>

<nav class="site-nav">
  

  
    <ul id="menu" class="menu">
      
        
        <li class="menu-item menu-item-home">
          <a href="/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-home"></i> <br />
            
            首页
          </a>
        </li>
      
        
        <li class="menu-item menu-item-archives">
          <a href="/archives" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-archive"></i> <br />
            
            归档
          </a>
        </li>
      
        
        <li class="menu-item menu-item-tags">
          <a href="/tags" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-tags"></i> <br />
            
            标签
          </a>
        </li>
      

      
    </ul>
  

  
</nav>

 </div>
    </header>

    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div id="content" class="content">
            

  <div id="posts" class="posts-expand">
    

  
  

  
  
  

  <article class="post post-type-normal " itemscope itemtype="http://schema.org/Article">

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
            
            
              
                YYModel解析（2）
              
            
          </h1>
        

        <div class="post-meta">
          <span class="post-time">
            <span class="post-meta-item-icon">
              <i class="fa fa-calendar-o"></i>
            </span>
            <span class="post-meta-item-text">发表于</span>
            <time itemprop="dateCreated" datetime="2016-09-28T10:37:09+08:00" content="2016-09-28">
              2016-09-28
            </time>
          </span>

          

          
            
          

          

          
          

          
        </div>
      </header>
    


    <div class="post-body" itemprop="articleBody">

      
      

      
        <h1 id="&#x524D;&#x8A00;"><a href="#&#x524D;&#x8A00;" class="headerlink" title="&#x524D;&#x8A00;"></a>&#x524D;&#x8A00;</h1><pre><code>YYModel&#x5305;&#x542B;&#x4E86;&#x5F88;&#x591A;&#x5E95;&#x5C42;&#x7684;&#x77E5;&#x8BC6;&#xFF0C;&#x5C06;&#x5176;&#x4E2D;&#x7684;&#x539F;&#x7406;&#x6478;&#x900F;&#xFF0C;&#x5BF9;&#x4E8E;&#x4EE5;&#x540E;&#x5B66;&#x4E60;&#x5176;&#x4ED6;&#x7684;&#x6846;&#x67B6;&#xFF0C;&#x751A;&#x81F3;&#x81EA;&#x5DF1;&#x5199;&#x4E00;&#x4E2A;&#x6846;&#x67B6;&#xFF0C;&#x90FD;&#x6709;&#x5F88;&#x5927;&#x7684;&#x5E2E;&#x52A9;&#x3002;&#x8BDD;&#x4E0D;&#x591A;&#x8BF4;&#xFF0C;&#x7EE7;&#x7EED;&#x5206;&#x6790;&#x3002;
</code></pre><h2 id="instancetype-classInfoWithClass-Class-cls"><a href="#instancetype-classInfoWithClass-Class-cls" class="headerlink" title="+ (instancetype)classInfoWithClass:(Class)cls"></a>+ (instancetype)classInfoWithClass:(Class)cls</h2><pre><code>+ (instancetype)classInfoWithClass:(Class)cls {
    if (!cls) return nil;
    static CFMutableDictionaryRef classCache;
    static CFMutableDictionaryRef metaCache;
    static dispatch_once_t onceToken;
    static dispatch_semaphore_t lock;
    dispatch_once(&amp;onceToken, ^{
        classCache = CFDictionaryCreateMutable(CFAllocatorGetDefault(), 0, &amp;kCFTypeDictionaryKeyCallBacks, &amp;kCFTypeDictionaryValueCallBacks);
        metaCache = CFDictionaryCreateMutable(CFAllocatorGetDefault(), 0, &amp;kCFTypeDictionaryKeyCallBacks, &amp;kCFTypeDictionaryValueCallBacks);
        lock = dispatch_semaphore_create(1);
    });
    dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);
    NSLog(@&quot;is meta %i&quot;,class_isMetaClass(cls));
    YYClassInfo *info = CFDictionaryGetValue(class_isMetaClass(cls) ? metaCache : classCache, (__bridge const void *)(cls));
    if (info &amp;&amp; info-&gt;_needUpdate) {
        [info _update];
    }
    dispatch_semaphore_signal(lock);
    if (!info) {
        info = [[YYClassInfo alloc] initWithClass:cls];
        if (info) {
            dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);
            CFDictionarySetValue(info.isMeta ? metaCache : classCache, (__bridge const void *)(cls), (__bridge const void *)(info));
            dispatch_semaphore_signal(lock);
        }
    }
    return info;
}
</code></pre><p>&#x7D27;&#x63A5;&#x4E0A;&#x6B21;&#x7684;&#x5206;&#x6790;&#xFF0C;&#x6211;&#x4EEC;&#x8FDB;&#x5165;&#x5230;&#x8FD9;&#x4E2A;&#x65B9;&#x6CD5;&#x540E;&#x9996;&#x5148;&#x770B;&#x5230;&#x4E86;4&#x4E2A;&#x9759;&#x6001;&#x53D8;&#x91CF;&#x58F0;&#x660E; classCache &#x548C; metaCache &#x662F;&#x4E3A;&#x4E86;&#x7533;&#x8BF7;&#x5B58;&#x50A8;&#x7A7A;&#x95F4;&#xFF0C;onceToken&#x548C;lock&#x65F6;&#x4E3A;&#x4E86;&#x7EBF;&#x7A0B;&#x5B89;&#x5168;&#xFF0C;&#x4E4B;&#x540E;&#x5728;&#x7EBF;&#x7A0B;&#x4E2D;&#x8C03;&#x7528;CFDictionaryCreateMutable&#x65B9;&#x6CD5;&#x6765;&#x83B7;&#x53D6;&#x4E00;&#x4E2A;CFDictionary&#x7684;&#x5185;&#x5B58;&#x7A7A;&#x95F4;&#xFF0C;&#x4E4B;&#x540E;&#x6765;&#x5230;&#x8FD9;&#x4E00;&#x53E5;<br>     YYClassInfo <em>info = CFDictionaryGetValue(class_isMetaClass(cls) ? metaCache : classCache, (__bridge const void </em>)(cls));<br>&#x6BCF;&#x4E00;&#x6B21;&#x6253;&#x5370;class_isMetaClass(cls)&#x90FD;&#x4E3A;0.&#x51FA;&#x8FD9;&#x4E00;&#x53E5;&#x8BDD;&#x662F;&#x5E72;&#x561B;&#x7528;&#x7684;&#x53FB;&#xFF1F;&#x8FD9;&#x91CC;&#x5E94;&#x8BE5;&#x662F;&#x5224;&#x65AD;object&#x7684;class&#x662F;&#x5426;&#x662F;&#x5143;&#x7C7B;&#xFF0C;&#x7136;&#x540E;&#x5224;&#x65AD;&#x662F;&#x5426;&#x9700;&#x8981;&#x66F4;&#x65B0;&#xFF0C;&#x8FD9;&#x91CC;&#x7684;&#x66F4;&#x65B0;&#x5E94;&#x8BE5;&#x662F;class&#x5C5E;&#x6027;&#x7684;&#x6539;&#x53D8;&#xFF08; <strong>&#x6211;&#x8FDB;&#x884C;&#x4E86;&#x5404;&#x79CD;&#x6539;&#x53D8;&#xFF0C;&#x4F46;&#x662F;&#x4E0D;&#x4F1A;&#x8FDB;&#x5230;&#x91CC;&#x9762;&#xFF0C;&#x5148;&#x7EE7;&#x7EED;&#x5206;&#x6790;&#xFF0C;&#x7A0D;&#x540E;&#x7814;&#x7A76;&#x8FD9;&#x4E2A;&#x95EE;&#x9898;</strong> &#xFF09;<br>&#x7136;&#x540E;&#x5230;&#x4E86;&#x5173;&#x952E;&#x7684;&#x4E00;&#x6B65;   <strong>info = [[YYClassInfo alloc] initWithClass:cls];</strong> &#x7EC8;&#x4E8E;&#x8981;&#x521D;&#x59CB;&#x5316;class&#x4E86; &#xFF0C;&#x6211;&#x4EEC;&#x8DF3;&#x8FDB;&#x53BB;&#x770B;&#x4E00;&#x770B;&#x3002;</p>
<pre><code>- (instancetype)initWithClass:(Class)cls {
    if (!cls) return nil;
    self = [super init];
    _cls = cls;
    _superCls = class_getSuperclass(cls);
    _isMeta = class_isMetaClass(cls);
    if (!_isMeta) {
        _metaCls = objc_getMetaClass(class_getName(cls));
    }
    _name = NSStringFromClass(cls);
    [self _update];

    _superClassInfo = [self.class classInfoWithClass:_superCls];
    return self;
}
</code></pre><p>_cls = cls&#x8FD9;&#x53E5;&#x5F88;&#x5BB9;&#x6613;&#x7406;&#x89E3;&#xFF0C;&#x5F53;&#x524D;&#x7C7B;&#x5C31;&#x662F;&#x4F60;&#x7684;&#x4F20;&#x5165;&#x7C7B;(&#x6253;&#x5370;&#x51FA;&#x6765;&#x7684;&#x662F;yybook)&#x3002;_superCls = class_getSuperclass(cls);(&#x7236;&#x7C7B; &#x4E5F;&#x5C31;&#x662F;NSObject)&#xFF0C; _isMeta = class_isMetaClass(cls);&#x662F;&#x4E0D;&#x662F;&#x5143;&#x7C7B;&#xFF0C;&#x5F53;&#x7136;&#x4E0D;&#x662F;&#x5143;&#x7C7B;&#x4E86;&#x3002;&#x6211;&#x4EEC;&#x5982;&#x679C;&#x6253;&#x5370;objc_getMetaClass(class_getName(cls))&#x5F97;&#x5230;&#x7684;&#x662F;yybook&#xFF0C;&#x5F53;&#x7136;yybook&#x7684;&#x5143;&#x7C7B;&#x5C31;&#x662F;yybook&#x3002;<strong>class&#x548C;metaClass&#x867D;&#x7136;&#x540D;&#x5B57;&#x4E00;&#x6837;&#xFF0C;&#x4F46;&#x4E0D;&#x662F;&#x540C;&#x4E00;&#x4E2A;&#x7C7B;&#x3002;</strong><br>&#x4E3A;&#x4E86;&#x66F4;&#x597D;&#x7684;&#x7406;&#x89E3;&#xFF0C;&#x8BF7;&#x770B;&#x56FE;<img src="http://www.ianisme.com/wp-content/uploads/2016/01/objective-runtime-1.png" alt=""></p>
<h3 id="void-update"><a href="#void-update" class="headerlink" title="-(void)_update"></a>-(void)_update</h3><p>_name&#x8FD9;&#x4E2A;&#x53C2;&#x6570;&#x7528;&#x6765;&#x4FDD;&#x5B58;&#x8BE5;&#x7C7B;&#x7684;&#x540D;&#x79F0;&#xFF0C;&#x7136;&#x540E;&#x6267;&#x884C;_update&#x65B9;&#x6CD5;&#xFF0C;&#x6211;&#x4EEC;&#x8FDB;&#x53BB;&#x770B;&#x4E00;&#x4E0B;</p>
<pre><code>- (void)_update {
    _ivarInfos = nil;
    _methodInfos = nil;
    _propertyInfos = nil;

    &#xFF0F;&#xFF0F;&#x7B2C;&#x4E00;&#x90E8;&#x5206;
    Class cls = self.cls;
    unsigned int methodCount = 0;
    Method *methods = class_copyMethodList(cls, &amp;methodCount);
    if (methods) {
        NSMutableDictionary *methodInfos = [NSMutableDictionary new];
        _methodInfos = methodInfos;
        for (unsigned int i = 0; i &lt; methodCount; i++) {
            YYClassMethodInfo *info = [[YYClassMethodInfo alloc] initWithMethod:methods[i]];
            if (info.name) methodInfos[info.name] = info;
        }
        free(methods);
    }
    &#xFF0F;&#xFF0F;&#x7B2C;&#x4E8C;&#x90E8;&#x5206;
    unsigned int propertyCount = 0;
    objc_property_t *properties = class_copyPropertyList(cls, &amp;propertyCount);
    if (properties) {
        NSMutableDictionary *propertyInfos = [NSMutableDictionary new];
        _propertyInfos = propertyInfos;
        for (unsigned int i = 0; i &lt; propertyCount; i++) {
            YYClassPropertyInfo *info = [[YYClassPropertyInfo alloc] initWithProperty:properties[i]];
            if (info.name) propertyInfos[info.name] = info;
        }
        free(properties);
    }
    &#xFF0F;&#xFF0F;&#x7B2C;&#x4E09;&#x90E8;&#x5206;
    unsigned int ivarCount = 0;
    Ivar *ivars = class_copyIvarList(cls, &amp;ivarCount);
    if (ivars) {
        NSMutableDictionary *ivarInfos = [NSMutableDictionary new];
        _ivarInfos = ivarInfos;
        for (unsigned int i = 0; i &lt; ivarCount; i++) {
            YYClassIvarInfo *info = [[YYClassIvarInfo alloc] initWithIvar:ivars[i]];
            if (info.name) ivarInfos[info.name] = info;
        }
        free(ivars);
    }

    if (!_ivarInfos) _ivarInfos = @{};
    if (!_methodInfos) _methodInfos = @{};
    if (!_propertyInfos) _propertyInfos = @{};

    _needUpdate = NO;
}
</code></pre><p>&#x6765;&#x5230;&#x8FD9;&#x4E2A;&#x65B9;&#x6CD5;&#xFF0C;&#x9996;&#x5148;</p>
<ul>
<li>_ivarInfos = nil;</li>
<li>_methodInfos = nil;</li>
<li>_propertyInfos = nil;</li>
</ul>
<p>&#x8FD9;&#x4E09;&#x884C;&#x521D;&#x59CB;&#x5316;&#x8D4B;&#x7A7A;&#xFF0C;Class cls = self.cls;&#x83B7;&#x53D6;&#x5F53;&#x524D;&#x7684;&#x7C7B;&#xFF0C; </p>
<h4 id="&#x7B2C;&#x4E00;&#x90E8;&#x5206;"><a href="#&#x7B2C;&#x4E00;&#x90E8;&#x5206;" class="headerlink" title="&#x7B2C;&#x4E00;&#x90E8;&#x5206;"></a>&#x7B2C;&#x4E00;&#x90E8;&#x5206;</h4><ul>
<li>unsigned int methodCount = 0;</li>
<li>Method *methods = class_copyMethodList(cls, &amp;methodCount);</li>
</ul>
<p>&#x7C7B;&#x65B9;&#x6CD5;&#x7684;&#x83B7;&#x53D6;&#xFF0C;&#x6211;&#x4EEC;&#x53EF;&#x4EE5;&#x5728;&#x4E0B;&#x65B9;&#x6DFB;&#x52A0;</p>
<pre><code>for (int i = 0; i&lt;methodCount; i++) {
       Method method = methods[i];
       SEL methodName = method_getName(method);
       const char *name = sel_getName(methodName);
       NSLog(@&quot;%s&quot;,name);
   }
</code></pre><p>&#x6765;&#x770B;&#x4E00;&#x4E0B;&#x83B7;&#x5F97;&#x7684;&#x65B9;&#x6CD5;&#x540D;</p>
<ul>
<li>2016-09-28 14:25:05.219 YYKitDemo[90901:1252671] pages</li>
<li>2016-09-28 14:25:05.219 YYKitDemo[90901:1252671] setPages:</li>
<li>2016-09-28 14:25:05.219 YYKitDemo[90901:1252671] publishDate6</li>
<li>2016-09-28 14:25:05.220 YYKitDemo[90901:1252671] setPublishDate6:</li>
<li>2016-09-28 14:25:05.220 YYKitDemo[90901:1252671] name</li>
<li>2016-09-28 14:25:05.220 YYKitDemo[90901:1252671] .cxx_destruct</li>
<li>2016-09-28 14:25:05.220 YYKitDemo[90901:1252671] setName:</li>
</ul>
<p>.cxx_destruct&#x662F;&#x4EC0;&#x4E48;&#x9B3C;&#xFF0C;&#x8BA9;&#x6211;&#x4EEC;&#x8C08;&#x4E0B;&#x4E00;&#x8BDD;&#x9898;&#x3002;&#xFF08;&#xFF0D;&#xFF0D;&#xFF0D;&#x8FD9;&#x91CC;&#x6253;&#x4E2A;&#x8BB0;&#x53F7;&#xFF0C;&#x7A0D;&#x540E;&#x518D;&#x7814;&#x7A76;&#x8FD9;&#x4E2A;&#x95EE;&#x9898;&#xFF09;&#x3002;  </p>
<pre><code>if (methods) {
    NSMutableDictionary *methodInfos = [NSMutableDictionary new];
    _methodInfos = methodInfos;
    for (unsigned int i = 0; i &lt; methodCount; i++) {
        YYClassMethodInfo *info = [[YYClassMethodInfo alloc] initWithMethod:methods[i]];
        if (info.name) methodInfos[info.name] = info;
    }
    free(methods);
}
</code></pre><p>&#x8FD9;&#x91CC;&#x5B9E;&#x4F8B;&#x5316;&#x4E00;&#x4E2A;&#x53EF;&#x53D8;&#x5B57;&#x5178;&#x7C7B;&#xFF0C;&#x7136;&#x540E;&#x5C06;&#x7C7B;&#x4E2D;&#x7684;&#x65B9;&#x6CD5;&#xFF08;&#x4E5F;&#x5C31;&#x662F;method&#x53D8;&#x91CF;&#x91CC;&#x5B58;&#x7684;&#x65B9;&#x6CD5;&#x540D;&#xFF09;&#x8F6C;&#x5316;&#x6210;&#x4E00;&#x4E2A;&#x7C7B;&#xFF0C;&#x4E5F;&#x5C31;&#x662F;&#x4E0B;&#x9762;</p>
<pre><code>@interface YYClassMethodInfo : NSObject
@property (nonatomic, assign, readonly) Method method;                  ///&lt; method opaque struct
@property (nonatomic, strong, readonly) NSString *name;                 ///&lt; method name
@property (nonatomic, assign, readonly) SEL sel;                        ///&lt; method&apos;s selector
@property (nonatomic, assign, readonly) IMP imp;                        ///&lt; method&apos;s implementation
@property (nonatomic, strong, readonly) NSString *typeEncoding;         ///&lt; method&apos;s parameter and return types
@property (nonatomic, strong, readonly) NSString *returnTypeEncoding;   ///&lt; return value&apos;s type
@property (nullable, nonatomic, strong, readonly) NSArray&lt;NSString *&gt; *argumentTypeEncodings; ///&lt; array of arguments&apos; type
</code></pre><p>&#x4E00;&#x4E2A;&#x65B9;&#x6CD5;&#x5728;runtime&#x4E2D;&#x5305;&#x542B;&#x4E86;&#x3001; sel(&#x65B9;&#x6CD5;&#x540D;&#x79F0;) , imp&#xFF08;&#x65B9;&#x6CD5;&#x7684;&#x5B9E;&#x73B0;&#xFF0C;&#x5176;&#x5B9E;&#x662F;&#x4E00;&#x4E2A;&#x7ED3;&#x6784;&#x4F53;&#xFF09; &#xFF0C;name&#xFF08;&#x65B9;&#x6CD5;&#x540D;&#x79F0;&#xFF09;&#xFF0C;&#x5269;&#x4E0B;&#x7684;&#x4E09;&#x4E2A;&#x53C2;&#x6570;&#x5982;&#x540C;&#x540E;&#x9762;&#x7684;&#x6CE8;&#x91CA;&#x6240;&#x793A;&#x3002;&#x770B;&#x5B8C;YYClassMethodInfo&#x8FD9;&#x4E2A;&#x7C7B;&#x4E4B;&#x540E;&#xFF0C;&#x6211;&#x4EEC;&#x5C31;&#x5F00;&#x59CB;&#x770B;&#x8FD9;&#x4E2A;&#x65B9;&#x6CD5; <strong>- (instancetype)initWithMethod:(Method)method</strong></p>
<pre><code>- (instancetype)initWithMethod:(Method)method {
    if (!method) return nil;
    self = [super init];
    _method = method;
    _sel = method_getName(method);
    _imp = method_getImplementation(method);
    const char *name = sel_getName(_sel);
    if (name) {
        _name = [NSString stringWithUTF8String:name];
    }
    const char *typeEncoding = method_getTypeEncoding(method);
    if (typeEncoding) {
        _typeEncoding = [NSString stringWithUTF8String:typeEncoding];
    }
    char *returnType = method_copyReturnType(method);
    if (returnType) {
        _returnTypeEncoding = [NSString stringWithUTF8String:returnType];
        free(returnType);
    }
    unsigned int argumentCount = method_getNumberOfArguments(method);
    if (argumentCount &gt; 0) {
        NSMutableArray *argumentTypes = [NSMutableArray new];
        for (unsigned int i = 0; i &lt; argumentCount; i++) {
            char *argumentType = method_copyArgumentType(method, i);
            NSString *type = argumentType ? [NSString stringWithUTF8String:argumentType] : nil;
            [argumentTypes addObject:type ? type : @&quot;&quot;];
            if (argumentType) free(argumentType);
        }
        _argumentTypeEncodings = argumentTypes;
    }
    return self;
}
</code></pre><ul>
<li>_sel = method_getName(method);</li>
<li>_imp = method_getImplementation(method);</li>
</ul>
<p>&#x8FD9;&#x4E24;&#x53E5;&#x5F88;&#x5BB9;&#x6613;&#x7406;&#x89E3;&#xFF0C;&#x76F4;&#x63A5;&#x83B7;&#x53D6;&#x65B9;&#x6CD5;&#x7684;&#x4E24;&#x4E2A;&#x5C5E;&#x6027;&#xFF0C;&#x63A5;&#x4E0B;&#x6765;&#x770B;&#x4E00;&#x4E0B;<strong>_typeEncoding</strong>&#x8FD9;&#x4E2A;&#x5C5E;&#x6027;&#xFF0C;&#x6CE8;&#x91CA;&#x662F;&#x8FD9;&#x6837;&#x5199;&#x7684;///&lt; method&#x2019;s parameter and return types&#xFF0C;&#x5C06;&#x5176;&#x6253;&#x5370;&#x4E4B;&#x540E;&#x5F97;&#x5230;&#x5982;&#x4E0B;&#x7684;&#x7ED3;&#x679C;</p>
<ul>
<li>2016-09-28 15:01:31.256 YYKitDemo[92905:1285455] type coding =  = Q16@0:8</li>
<li>2016-09-28 15:01:42.520 YYKitDemo[92905:1285455] type coding =  = v24@0:8Q16</li>
<li>2016-09-28 15:01:43.595 YYKitDemo[92905:1285455] type coding =  = @16@0:8</li>
<li>2016-09-28 15:01:44.345 YYKitDemo[92905:1285455] type coding =  = v24@0:8@16</li>
<li>2016-09-28 15:01:45.129 YYKitDemo[92905:1285455] type coding =  = @16@0:8</li>
<li>2016-09-28 15:01:45.863 YYKitDemo[92905:1285455] type coding =  = v16@0:8</li>
<li>2016-09-28 15:01:46.580 YYKitDemo[92905:1285455] type coding =  = v24@0:8@16</li>
</ul>
<p>&#x8FD9;&#x4E9B;&#x90FD;&#x662F;&#x4EC0;&#x4E48;&#x9B3C;&#xFF0D; &#xFF0D; &#x6CA1;&#x5173;&#x7CFB; &#xFF0C;&#x6211;&#x4EEC;&#x6709;&#x8FD9;&#x7BC7;<a href="http://www.jianshu.com/p/f4129b5194c0" target="_blank" rel="external">&#x6587;&#x7AE0;</a>&#x5E2E;&#x52A9;&#x6211;&#x4EEC;&#x3002;&#x6211;&#x4EEC;&#x53EF;&#x4EE5;&#x53D1;&#x73B0;&#x8FD9;7&#x4E2A;typeencoding&#x5176;&#x5B9E;&#x5C31;&#x662F;&#x524D;&#x9762;7&#x4E2A;&#x65B9;&#x6CD5;&#x7684;string&#x503C;&#x3002;&#x63A5;&#x4E0B;&#x6765;&#x7EE7;&#x7EED;&#x770B;&#x4EE3;&#x7801;</p>
<pre><code>char *returnType = method_copyReturnType(method);
    if (returnType) {
        _returnTypeEncoding = [NSString stringWithUTF8String:returnType];
        NSLog(@&quot;returnTypeEncoding -- %@&quot;,_returnTypeEncoding);
        free(returnType);
    }
</code></pre><p>&#x8FD9;&#x91CC;&#x5F97;&#x5230;&#x7684;&#x7ED3;&#x679C;<br>returnTypeEncoding &#x2013; @ &#x6216;&#x8005; returnTypeEncoding &#x2013; v,&#x5176;&#x5B9E;&#x5C31;&#x662F;&#x51FD;&#x6570;&#x8FD4;&#x56DE;&#x503C;&#x7C7B;&#x578B;&#x7684;string&#x8868;&#x793A;&#x5F62;&#x5F0F;&#x3002;</p>
<pre><code>if (argumentCount &gt; 0) {
        NSMutableArray *argumentTypes = [NSMutableArray new];
        for (unsigned int i = 0; i &lt; argumentCount; i++) {
            char *argumentType = method_copyArgumentType(method, i);
            NSString *type = argumentType ? [NSString stringWithUTF8String:argumentType] : nil;
            NSLog(@&quot;type  &#xFF1D;&#xFF1D;&#xFF1D;&#xFF1D; %@&quot;,type);
            [argumentTypes addObject:type ? type : @&quot;&quot;];
            if (argumentType) free(argumentType);
        }
        _argumentTypeEncodings = argumentTypes;
    }
</code></pre><p>&#x8FD9;&#x4E00;&#x6BB5;&#x662F;&#x4EC0;&#x4E48;&#x610F;&#x601D;&#x5462;&#xFF0C;&#x8BA9;&#x6211;&#x4EEC;&#x6765;&#x770B;&#x4E00;&#x4E0B;&#x5176;&#x4E2D;&#x4E00;&#x6BB5;&#x7684;&#x8F93;&#x51FA;&#x7ED3;&#x679C;<br> 2016-09-28 15:58:20.679 YYKitDemo[95259:1325369] type coding =  = v24@0:8@16<br>2016-09-28 15:58:20.679 YYKitDemo[95259:1325369] returnTypeEncoding &#x2013; v<br>2016-09-28 16:01:56.587 YYKitDemo[95259:1325369] 3<br>2016-09-28 16:01:56.587 YYKitDemo[95259:1325369] type  &#xFF1D;&#xFF1D;&#xFF1D;&#xFF1D; @<br>2016-09-28 16:01:56.587 YYKitDemo[95259:1325369] type  &#xFF1D;&#xFF1D;&#xFF1D;&#xFF1D; :<br>2016-09-28 16:01:56.588 YYKitDemo[95259:1325369] type  &#xFF1D;&#xFF1D;&#xFF1D;&#xFF1D; @<br>&#x8FD9;&#x91CC;&#x9762;&#x5B58;&#x7684;&#x5C31;&#x662F;&#x51FD;&#x6570;&#x91CC;&#x7684;&#x5305;&#x542B;&#x7684;&#x53C2;&#x6570;&#x7C7B;&#x578B;&#x3002;</p>
<p>&#x63A5;&#x7740;&#x5C06;argumenttype&#x8F6C;&#x6362;&#x6210;nsstring&#x7C7B;&#x578B;&#x7684;&#x5BF9;&#x8C61;&#x4FDD;&#x5B58;&#x5230;_argumentTypeEncodings&#x7684;&#x6570;&#x7EC4;&#x4E2D;&#x3002;&#x6700;&#x540E;return self&#xFF0C;&#x81F3;&#x6B64;&#x5B8C;&#x6210;&#x4E86;&#x4E00;&#x4E2A;&#x65B9;&#x6CD5;&#x6A21;&#x578B;&#x7684;&#x5C01;&#x88C5;&#x3002;</p>
<h4 id="&#x7B2C;&#x4E8C;&#x90E8;&#x5206;"><a href="#&#x7B2C;&#x4E8C;&#x90E8;&#x5206;" class="headerlink" title="&#x7B2C;&#x4E8C;&#x90E8;&#x5206;"></a>&#x7B2C;&#x4E8C;&#x90E8;&#x5206;</h4><pre><code>&#xFF0F;&#xFF0F;&#x7B2C;&#x4E8C;&#x90E8;&#x5206;
    unsigned int propertyCount = 0;
    objc_property_t *properties = class_copyPropertyList(cls, &amp;propertyCount);
    if (properties) {
        NSMutableDictionary *propertyInfos = [NSMutableDictionary new];
        _propertyInfos = propertyInfos;
        for (unsigned int i = 0; i &lt; propertyCount; i++) {
            YYClassPropertyInfo *info = [[YYClassPropertyInfo alloc] initWithProperty:properties[i]];
            if (info.name) propertyInfos[info.name] = info;
        }
        free(properties);
    }
</code></pre><p>&#x7B2C;&#x4E8C;&#x90E8;&#x5206;&#x662F;&#x5BF9;propertyCount&#x7684;&#x5C01;&#x88C5;&#xFF0C;objc_property_t *properties = class_copyPropertyList(cls, &amp;propertyCount);&#x662F;&#x83B7;&#x53D6;&#x5404;&#x4E2A;&#x5C5E;&#x6027;&#xFF0C;</p>
<pre><code>/**
 Property information.
 */
@interface YYClassPropertyInfo : NSObject
@property (nonatomic, assign, readonly) objc_property_t property; ///&lt; property&apos;s opaque struct
@property (nonatomic, strong, readonly) NSString *name;           ///&lt; property&apos;s name
@property (nonatomic, assign, readonly) YYEncodingType type;      ///&lt; property&apos;s type
@property (nonatomic, strong, readonly) NSString *typeEncoding;   ///&lt; property&apos;s encoding value
@property (nonatomic, strong, readonly) NSString *ivarName;       ///&lt; property&apos;s ivar name
@property (nullable, nonatomic, assign, readonly) Class cls;      ///&lt; may be nil
@property (nullable, nonatomic, strong, readonly) NSArray&lt;NSString *&gt; *protocols; ///&lt; may nil
@property (nonatomic, assign, readonly) SEL getter;               ///&lt; getter (nonnull)
@property (nonatomic, assign, readonly) SEL setter;               ///&lt; setter (nonnull)
</code></pre><p>&#x7B2C;&#x4E00;&#x4E2A;&#x53C2;&#x6570;&#x662F;&#x4E00;&#x4E2A;property&#x7684;&#x4E00;&#x4E2A;&#x7ED3;&#x6784;&#x4F53;&#xFF0C;&#x7ED3;&#x6784;&#x4F53;&#x91CC;&#x9762;&#x4FDD;&#x5B58;&#x8FD9;&#x4E2A;property&#x7684;&#x5404;&#x79CD;&#x5C5E;&#x6027;&#xFF0C;&#x7B2C;&#x4E8C;&#x4E2A;&#x53C2;&#x6570;&#x662F;name&#xFF0C;YYEncodingType&#x5C5E;&#x6027;&#x7684;&#x7C7B;&#x578B;&#xFF0C;typeencoding&#x662F;&#x5C5E;&#x6027;&#x6240;&#x6709;&#x7684;&#x7C7B;&#x578B;&#x7F16;&#x7801;&#xFF0C;ivarName&#x5C31;&#x662F;&#x5C5E;&#x6027;&#x540D;&#xFF0C;&#x6BD4;&#x5982;_name&#xFF0C;protocols&#x534F;&#x8BAE;&#xFF0C;getter  &#x548C; setter &#x4E0D;&#x7528;&#x8BF4; &#x662F;&#x751F;&#x6210;&#x7684;&#x4E24;&#x4E2A;&#x65B9;&#x6CD5;&#x3002;<br>&#x63A5;&#x4E0B;&#x6765;&#x6211;&#x4EEC;&#x770B;  <strong>- (instancetype)initWithProperty:(objc_property_t)property</strong></p>
<pre><code>- (instancetype)initWithProperty:(objc_property_t)property
   - (instancetype)initWithProperty:(objc_property_t)property {
      //&#x7B2C;&#x4E00;&#x90E8;&#x5206;
       if (!property) return nil;
       self = [super init];
       _property = property;
       const char *name = property_getName(property);
       if (name) {
           _name = [NSString stringWithUTF8String:name];
       }

       //&#x7B2C;&#x4E8C;&#x90E8;&#x5206;
       YYEncodingType type = 0;
       unsigned int attrCount;
       objc_property_attribute_t *attrs = property_copyAttributeList(property, &amp;attrCount);
       for (unsigned int i = 0; i &lt; attrCount; i++) {
           switch (attrs[i].name[0]) {
               case &apos;T&apos;: { // Type encoding
                   if (attrs[i].value) {
                       _typeEncoding = [NSString stringWithUTF8String:attrs[i].value];
                       type = YYEncodingGetType(attrs[i].value);                        
                   if ((type &amp; YYEncodingTypeMask) == YYEncodingTypeObject &amp;&amp; _typeEncoding.length) {
                       NSScanner *scanner = [NSScanner scannerWithString:_typeEncoding];
                       if (![scanner scanString:@&quot;@\&quot;&quot; intoString:NULL]) continue;

                       NSString *clsName = nil;
                       if ([scanner scanUpToCharactersFromSet: [NSCharacterSet characterSetWithCharactersInString:@&quot;\&quot;&lt;&quot;] intoString:&amp;clsName]) {
                           if (clsName.length) _cls = objc_getClass(clsName.UTF8String);
                       }

                       NSMutableArray *protocols = nil;
                       while ([scanner scanString:@&quot;&lt;&quot; intoString:NULL]) {
                           NSString* protocol = nil;
                           if ([scanner scanUpToString:@&quot;&gt;&quot; intoString: &amp;protocol]) {
                               if (protocol.length) {
                                   if (!protocols) protocols = [NSMutableArray new];
                                   [protocols addObject:protocol];
                               }
                           }
                           [scanner scanString:@&quot;&gt;&quot; intoString:NULL];
                       }
                       _protocols = protocols;
                   }
               }
           } break;
           case &apos;V&apos;: { // Instance variable
               if (attrs[i].value) {
                   _ivarName = [NSString stringWithUTF8String:attrs[i].value];
               }
           } break;
           case &apos;R&apos;: {
               type |= YYEncodingTypePropertyReadonly;
           } break;
           case &apos;C&apos;: {
               type |= YYEncodingTypePropertyCopy;
           } break;
           case &apos;&amp;&apos;: {
               type |= YYEncodingTypePropertyRetain;
           } break;
           case &apos;N&apos;: {
               type |= YYEncodingTypePropertyNonatomic;
           } break;
           case &apos;D&apos;: {
               type |= YYEncodingTypePropertyDynamic;
           } break;
           case &apos;W&apos;: {
               type |= YYEncodingTypePropertyWeak;
           } break;
           case &apos;G&apos;: {
               type |= YYEncodingTypePropertyCustomGetter;
               if (attrs[i].value) {
                   _getter = NSSelectorFromString([NSString stringWithUTF8String:attrs[i].value]);
               }
           } break;
           case &apos;S&apos;: {
               type |= YYEncodingTypePropertyCustomSetter;
               if (attrs[i].value) {
                   _setter = NSSelectorFromString([NSString stringWithUTF8String:attrs[i].value]);
               }
           } // break; commented for code coverage in next line
           default: break;
       }


       }
       if (attrs) {
           free(attrs);
           attrs = NULL;
       }

       _type = type;
       if (_name.length) {
           if (!_getter) {
               _getter = NSSelectorFromString(_name);
           }
           if (!_setter) {
               _setter = NSSelectorFromString([NSString stringWithFormat:@&quot;set%@%@:&quot;, [_name substringToIndex:1].uppercaseString, [_name substringFromIndex:1]]);
           }
       }
       return self;
   }
</code></pre><h6 id="part-one"><a href="#part-one" class="headerlink" title="part one"></a>part one</h6><p>&#x7B2C;&#x4E00;&#x90E8;&#x5206;&#x8D4B;&#x503C;&#xFF0C;&#x5224;&#x65AD;&#x7A7A;&#x503C;&#xFF0C;&#x4F7F;&#x7528;property_getName&#x65B9;&#x6CD5;&#x83B7;&#x53D6;&#x5C5E;&#x6027;&#x540D;&#xFF0C;&#x6CA1;&#x6709;&#x4EC0;&#x4E48; &#x5185;&#x5BB9; &#xFF0C;&#x6211;&#x4EEC;&#x770B;&#x7B2C;&#x4E8C;&#x90E8;&#x5206;&#x3002;</p>
<pre><code>if (!property) return nil;
  self = [super init];
  _property = property;
  const char *name = property_getName(property);
  if (name) {
      _name = [NSString stringWithUTF8String:name];
      NSLog(@&quot;%@&quot;,_name);
  }
</code></pre><h6 id="part-two"><a href="#part-two" class="headerlink" title="part two"></a>part two</h6><p>&#x7B2C;&#x4E8C;&#x90E8;&#x5206;&#x5F88;&#x957F;&#xFF0C;&#x6211;&#x622A;&#x53D6;&#x4E3B;&#x8981;&#x7684;&#x90E8;&#x5206;</p>
<pre><code>YYEncodingType type = 0;
 unsigned int attrCount;
 objc_property_attribute_t *attrs = property_copyAttributeList(property, &amp;attrCount);
 for (unsigned int i = 0; i &lt; attrCount; i++) {
     switch (attrs[i].name[0]) {
         case &apos;T&apos;: { // Type encoding
             if (attrs[i].value) {
                 _typeEncoding = [NSString stringWithUTF8String:attrs[i].value];
                 type = YYEncodingGetType(attrs[i].value);

             if ((type &amp; YYEncodingTypeMask) == YYEncodingTypeObject &amp;&amp; _typeEncoding.length) {
                 NSScanner *scanner = [NSScanner scannerWithString:_typeEncoding];
                 if (![scanner scanString:@&quot;@\&quot;&quot; intoString:NULL]) continue;

                 NSString *clsName = nil;
                 if ([scanner scanUpToCharactersFromSet: [NSCharacterSet characterSetWithCharactersInString:@&quot;\&quot;&lt;&quot;] intoString:&amp;clsName]) {
                     if (clsName.length) _cls = objc_getClass(clsName.UTF8String);
                 }

                 NSMutableArray *protocols = nil;
                 while ([scanner scanString:@&quot;&lt;&quot; intoString:NULL]) {
                     NSString* protocol = nil;
                     if ([scanner scanUpToString:@&quot;&gt;&quot; intoString: &amp;protocol]) {
                         if (protocol.length) {
                             if (!protocols) protocols = [NSMutableArray new];
                             [protocols addObject:protocol];
                         }
                     }
                     [scanner scanString:@&quot;&gt;&quot; intoString:NULL];
                 }
                 _protocols = protocols;
             }
         }
     } break;
     case &apos;V&apos;: { // Instance variable
         if (attrs[i].value) {
             _ivarName = [NSString stringWithUTF8String:attrs[i].value];
         }
     } break;
</code></pre><p>&#x9996;&#x5148;&#x58F0;&#x660E;&#x4E86;&#x4E00;&#x4E2A;YYEncodingType&#x53D8;&#x91CF; &#x548C; &#x4E00;&#x4E2A;attrCount&#x53D8;&#x91CF;&#xFF0C;&#x63A5;&#x7740;&#x83B7;&#x53D6;objc_property_attribute_t *attrs = property_copyAttributeList(property, &amp;attrCount); &#x770B;&#x5230;attribute&#x5927;&#x5BB6;&#x6216;&#x8BB8;&#x4F1A;&#x731C;&#x5230;&#x8FD9;&#x91CC;&#x83B7;&#x53D6;&#x7684;&#x662F;&#x4EC0;&#x4E48;&#x4E86;&#xFF0C;&#x672C;&#x7740;&#x5B9E;&#x4E8B;&#x6C42;&#x662F;&#x7684;&#x539F;&#x5219;&#xFF0C;&#x6211;&#x4EEC;&#x5C06;&#x5B83;&#x6253;&#x5370;&#x51FA;&#x6765;&#x770B;&#x4E00;&#x4E0B;</p>
<ul>
<li>2016-09-29 09:41:06.694 YYKitDemo[11551:1551862] name</li>
<li>2016-09-29 09:41:08.442 YYKitDemo[11551:1551862] T</li>
<li>2016-09-29 09:41:08.442 YYKitDemo[11551:1551862] C</li>
<li>2016-09-29 09:41:08.443 YYKitDemo[11551:1551862] N</li>
<li>2016-09-29 09:41:08.443 YYKitDemo[11551:1551862] V</li>
</ul>
<table>
<thead>
<tr>
<th>&#x5E38;&#x7528;attribute</th>
<th>name</th>
<th>value</th>
</tr>
</thead>
<tbody>
<tr>
<td>nonatomic</td>
<td>&#x201C;N&#x201D;</td>
<td>&#x201C;&#x201D;</td>
</tr>
<tr>
<td>strong/retain</td>
<td>&#x201C;&amp;&#x201D;</td>
<td>&#x201C;&#x201D;</td>
</tr>
<tr>
<td>weak</td>
<td>&#x201C;W&#x201D;</td>
<td>&#x201C;&#x201D;</td>
</tr>
<tr>
<td>&#x5C5E;&#x6027;&#x7684;&#x7C7B;&#x578B;type</td>
<td>&#x201C;T&#x201D;</td>
<td>&#x201C;@TypeName&#x201D;, eg&#xFF08;&#x4F8B;&#x5982;&#xFF09;&#x201D;@\&#x201D;NSString\&#x201D;&#x201D;</td>
</tr>
<tr>
<td>&#x5C5E;&#x6027;&#x5BF9;&#x5E94;&#x7684;&#x5B9E;&#x4F8B;&#x53D8;&#x91CF;Ivar</td>
<td>&#x201C;V&#x201D;</td>
<td>&#x201C;Ivar_name&#x201D;, eg(&#x4F8B;&#x5982;) &#x201C;_name&#x201D;</td>
</tr>
<tr>
<td>readonly</td>
<td>&#x201C;R&#x201D;</td>
<td>&#x201C;&#x201D;</td>
</tr>
<tr>
<td>getter</td>
<td>&#x201C;G&#x201D;</td>
<td>&#x201C;GetterName&#x201D;, eg(&#x4F8B;&#x5982;)&#x201D;isRight&#x201D;</td>
</tr>
<tr>
<td>setter</td>
<td>&#x201C;S&#x201D;</td>
<td>&#x201C;SetterName&#x201D;, eg(&#x4F8B;&#x5982;)&#x201D;setName&#x201D;</td>
</tr>
<tr>
<td>assign/atomic</td>
<td>&#x9ED8;&#x8BA4;&#x5373;&#x4E3A;assign&#x548C;retain</td>
<td></td>
</tr>
<tr>
<td>copy</td>
<td>&#x201C;C&#x201D;</td>
</tr>
</tbody>
</table>
<p>&#x53C2;&#x7167;&#x8FD9;&#x4E2A;&#x8868;&#x683C; &#x6211;&#x4EEC;&#x53EF;&#x4EE5;&#x8FD8;&#x539F;&#x4E00;&#x4E0B;NString   copy  nonatomic  &#xFF0D;&#xFF0D;v&#x5E94;&#x8BE5;&#x662F;&#x6307;&#x9488;&#x7C7B;&#x578B; void* &#x7A7A;&#x7C7B;&#x578B;&#x6307;&#x9488;&#xFF0C; &#x5982;&#x679C;&#x4F60;&#x6709;&#x66F4;&#x597D;&#x7684;&#x7B54;&#x6848;&#xFF0C;&#x8BF7;&#x544A;&#x8BC9;&#x6211;&#x3002;&#xFF08;qq:125668733&#xFF09;</p>
<p>ok&#xFF0C;&#x63A5;&#x4E0B;&#x6765;&#x5206;&#x6790; T &#x8FD9;&#x4E2A;&#x5224;&#x65AD;&#xFF0C;T&#x662F;&#x5C5E;&#x6027;&#x7684;&#x7C7B;&#x578B;&#xFF0C;&#x5305;&#x62EC;NSString ,NSData&#x7B49;&#x7B49;&#xFF0C;&#x6240;&#x4EE5;&#x6211;&#x4EEC;&#x9700;&#x8981;&#x7279;&#x522B;&#x5904;&#x7406;&#x4E00;&#x4E0B;&#xFF0C;<br> _typeEncoding = [NSString stringWithUTF8String:attrs[i].value];<br> &#x9996;&#x5148;&#x8BB0;&#x5F55;&#x4E0B;&#x7C7B;&#x578B;&#x7684;string<br> type = YYEncodingGetType(attrs[i].value);<br> &#x7136;&#x540E;&#x4F7F;&#x7528;YYEncodingGetType&#x65B9;&#x6CD5;&#x6765;&#x83B7;&#x53D6;YYEncodingType&#xFF0C;&#x6211;&#x4EEC;&#x8FDB;&#x5165;&#x5230;<strong>YYEncodingType</strong>&#x91CC;&#x9762;&#x770B;&#x4E00;&#x4E0B;</p>
<pre><code> YYEncodingType YYEncodingGetType(const char *typeEncoding) {
    char *type = (char *)typeEncoding;
    if (!type) return YYEncodingTypeUnknown;
    size_t len = strlen(type);
    if (len == 0) return YYEncodingTypeUnknown;   
YYEncodingType qualifier = 0;
bool prefix = true;
while (prefix) {
    switch (*type) {
        case &apos;r&apos;: {
            qualifier |= YYEncodingTypeQualifierConst;
            type++;
        } break;
        case &apos;n&apos;: {
            qualifier |= YYEncodingTypeQualifierIn;
            type++;
        } break;
        case &apos;N&apos;: {
            qualifier |= YYEncodingTypeQualifierInout;
            type++;
        } break;
        case &apos;o&apos;: {
            qualifier |= YYEncodingTypeQualifierOut;
            type++;
        } break;
        case &apos;O&apos;: {
            qualifier |= YYEncodingTypeQualifierBycopy;
            type++;
        } break;
        case &apos;R&apos;: {
            qualifier |= YYEncodingTypeQualifierByref;
            type++;
        } break;
        case &apos;V&apos;: {
            qualifier |= YYEncodingTypeQualifierOneway;
            type++;
        } break;
        default: { prefix = false; } break;
    }
}

len = strlen(type);
if (len == 0) return YYEncodingTypeUnknown | qualifier;

switch (*type) {
    case &apos;v&apos;: return YYEncodingTypeVoid | qualifier;
    case &apos;B&apos;: return YYEncodingTypeBool | qualifier;
    case &apos;c&apos;: return YYEncodingTypeInt8 | qualifier;
    case &apos;C&apos;: return YYEncodingTypeUInt8 | qualifier;
    case &apos;s&apos;: return YYEncodingTypeInt16 | qualifier;
    case &apos;S&apos;: return YYEncodingTypeUInt16 | qualifier;
    case &apos;i&apos;: return YYEncodingTypeInt32 | qualifier;
    case &apos;I&apos;: return YYEncodingTypeUInt32 | qualifier;
    case &apos;l&apos;: return YYEncodingTypeInt32 | qualifier;
    case &apos;L&apos;: return YYEncodingTypeUInt32 | qualifier;
    case &apos;q&apos;: return YYEncodingTypeInt64 | qualifier;
    case &apos;Q&apos;: return YYEncodingTypeUInt64 | qualifier;
    case &apos;f&apos;: return YYEncodingTypeFloat | qualifier;
    case &apos;d&apos;: return YYEncodingTypeDouble | qualifier;
    case &apos;D&apos;: return YYEncodingTypeLongDouble | qualifier;
    case &apos;#&apos;: return YYEncodingTypeClass | qualifier;
    case &apos;:&apos;: return YYEncodingTypeSEL | qualifier;
    case &apos;*&apos;: return YYEncodingTypeCString | qualifier;
    case &apos;^&apos;: return YYEncodingTypePointer | qualifier;
    case &apos;[&apos;: return YYEncodingTypeCArray | qualifier;
    case &apos;(&apos;: return YYEncodingTypeUnion | qualifier;
    case &apos;{&apos;: return YYEncodingTypeStruct | qualifier;
    case &apos;@&apos;: {
        if (len == 2 &amp;&amp; *(type + 1) == &apos;?&apos;)
            return YYEncodingTypeBlock | qualifier;
        else
            return YYEncodingTypeObject | qualifier;
    }
    default: return YYEncodingTypeUnknown | qualifier;
}
}
</code></pre><p>&#x5148;&#x770B;&#x4E00;&#x4E0B;&#x5F00;&#x5934;</p>
<ul>
<li>char <em>type = (char </em>)typeEncoding;</li>
<li>if (!type) return YYEncodingTypeUnknown;</li>
<li>size_t len = strlen(type);</li>
<li>if (len == 0) return YYEncodingTypeUnknown;</li>
</ul>
<p>&#x8FD9;&#x91CC;&#x5BF9;&#x6570;&#x636E;&#x662F;&#x5426;&#x4E3A;&#x7A7A;&#x7684;&#x5224;&#x65AD;&#x3002; </p>
<pre><code>YYEncodingType qualifier = 0;
    bool prefix = true;
    while (prefix) {
        switch (*type) {
            case &apos;r&apos;: {
                qualifier |= YYEncodingTypeQualifierConst;
                type++;
            } break;
            case &apos;n&apos;: {
                qualifier |= YYEncodingTypeQualifierIn;
                type++;
            } break;
            case &apos;N&apos;: {
                qualifier |= YYEncodingTypeQualifierInout;
                type++;
            } break;
            case &apos;o&apos;: {
                qualifier |= YYEncodingTypeQualifierOut;
                type++;
            } break;
            case &apos;O&apos;: {
                qualifier |= YYEncodingTypeQualifierBycopy;
                type++;
            } break;
            case &apos;R&apos;: {
                qualifier |= YYEncodingTypeQualifierByref;
                type++;
            } break;
            case &apos;V&apos;: {
                qualifier |= YYEncodingTypeQualifierOneway;
                type++;
            } break;
            default: { prefix = false; } break;
        }
    }
</code></pre><p>&#x8FD9;&#x91CC;&#x5BF9;&#x4E8E;type++&#x4E0D;&#x7406;&#x89E3;&#xFF0C;&#x5148;&#x628A;type&#x6253;&#x5370;&#x51FA;&#x6765;&#xFF0C;&#x6BCF;&#x6B21;type++&#x4E4B;&#x540E;&#x90FD;&#x628A;&#x7ED3;&#x679C;&#x6253;&#x5370;&#x51FA;&#x6765;&#xFF0C;&#x5F97;&#x5230;<br>@ &#x201C; N S S t r i n &#x3002;&#x3002;&#x3002;&#x3002;&#x3002;&#x3002;<br>&#x731C;&#x6D4B;&#xFF1A;&#x5BF9;&#x4E8E;&#x7C7B;&#x578B;&#x7F16;&#x7801;&#x7684;&#x4E00;&#x79CD;&#x904D;&#x5386;<br>&#x5176;&#x4E2D; |= &#x7684;&#x7B26;&#x53F7; &#x662F; &#x5F02;&#x6216; &#x8FD0;&#x7B97;&#xFF0C; &#x6BD4;&#x5982;  0001 &#xFF5C;&#xFF1D; 0010 &#xFF1D; 0011  &#xFF0C;&#x5177;&#x4F53;&#x8FD0;&#x7528;&#x4E3E;&#x4E2A;&#x4F8B;&#x5B50;&#xFF0C;&#x4E00;&#x4E2A;&#x7528;&#x6237;&#x7684;&#x6743;&#x9650; &#x662F; 0001 &#xFF0C;&#x5982;&#x679C;&#x7ED9;&#x4ED6;&#x589E;&#x52A0;&#x6743;&#x9650;A &#x90A3;&#x4E48;&#x6211;&#x4EEC;&#x53EA;&#x8981;&#x5B9A;&#x4E49;&#x6743;&#x9650;A&#x7684;&#x6743;&#x9650;&#x662F; 0011 &#xFF0C;&#x53EA;&#x8981;&#x8FDB;&#x884C;&#x5F02;&#x6216;&#x8FD0;&#x7B97;&#xFF0C;&#x5C31;&#x53EF;&#x4EE5;&#x8D4B;&#x7ED9;&#x7528;&#x6237;&#x6743;&#x9650;&#x3002;<br>    len = strlen(type);<br>    if (len == 0) return YYEncodingTypeUnknown | qualifier;<br>&#x5BB9;&#x9519;&#x5904;&#x7406;&#x3002;</p>
<pre><code>switch (*type)
&#xFF5B;
    &#x3002;&#x3002;&#x3002;
     case &apos;@&apos;: {
            if (len == 2 &amp;&amp; *(type + 1) == &apos;?&apos;)
                return YYEncodingTypeBlock | qualifier;
            else
                return YYEncodingTypeObject | qualifier;
        }
&#xFF5D;
</code></pre><p>&#x7C7B;&#x578B;&#x5224;&#x65AD;&#xFF0C;&#x5176;&#x4E2D;case &#x2018;@&#x2019;&#x91CC;&#x9762;&#x6709;&#x4E24;&#x4E2A;&#x5224;&#x65AD;&#xFF0C;&#x5224;&#x65AD;&#x662F;&#x5426;&#x662F;block&#x8FD8;&#x6709;&#x662F;&#x5426;&#x662F;object&#x3002;*(type + 1)</p>
<pre><code>if ((type &amp; YYEncodingTypeMask) == YYEncodingTypeObject &amp;&amp; _typeEncoding.length) {
                        NSScanner *scanner = [NSScanner scannerWithString:_typeEncoding];
                        if (![scanner scanString:@&quot;@\&quot;&quot; intoString:NULL]) continue;

                    NSString *clsName = nil;
                    if ([scanner scanUpToCharactersFromSet: [NSCharacterSet characterSetWithCharactersInString:@&quot;\&quot;&lt;&quot;] intoString:&amp;clsName]) {
                        if (clsName.length) _cls = objc_getClass(clsName.UTF8String);
                    }

                    NSMutableArray *protocols = nil;
                    while ([scanner scanString:@&quot;&lt;&quot; intoString:NULL]) {
                        NSString* protocol = nil;
                        if ([scanner scanUpToString:@&quot;&gt;&quot; intoString: &amp;protocol]) {
                            if (protocol.length) {
                                if (!protocols) protocols = [NSMutableArray new];
                                [protocols addObject:protocol];
                            }
                        }
                        [scanner scanString:@&quot;&gt;&quot; intoString:NULL];
                    }
                    _protocols = protocols;
                }
</code></pre>
      
    </div>

    <div>
      
        

      
    </div>

    <div>
      
        

      
    </div>

    <footer class="post-footer">
      

      
        <div class="post-nav">
          <div class="post-nav-next post-nav-item">
            
              <a href="/2016/09/26/yymodel解析1/" rel="next" title="第一篇博客:YYModel解析（1）">
                <i class="fa fa-chevron-left"></i> 第一篇博客:YYModel解析（1）
              </a>
            
          </div>

          <div class="post-nav-prev post-nav-item">
            
              <a href="/2016/10/09/---/" rel="prev" title="">
                 <i class="fa fa-chevron-right"></i>
              </a>
            
          </div>
        </div>
      

      
      
    </footer>
  </article>



    <div class="post-spread">
      
    </div>
  </div>


          </div>
          


          
  <div class="comments" id="comments">
    
  </div>


        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    <div class="sidebar-inner">

      

      
        <ul class="sidebar-nav motion-element">
          <li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap" >
            文章目录
          </li>
          <li class="sidebar-nav-overview" data-target="site-overview">
            站点概览
          </li>
        </ul>
      

      <section class="site-overview sidebar-panel ">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
          <img class="site-author-image" itemprop="image"
               src="/images/avatar.gif"
               alt="Motom" />
          <p class="site-author-name" itemprop="name">Motom</p>
          <p class="site-description motion-element" itemprop="description">Hi! 欢迎来到我的博客，希望这里的知识能够帮助到你！</p>
        </div>
        <nav class="site-state motion-element">
          <div class="site-state-item site-state-posts">
            <a href="/archives">
              <span class="site-state-item-count">3</span>
              <span class="site-state-item-name">日志</span>
            </a>
          </div>

          

          

        </nav>

        

        <div class="links-of-author motion-element">
          
        </div>

        
        

        
        

      </section>

      
        <section class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active">
          <div class="post-toc">
            
              
            
            
              <div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#前言"><span class="nav-number">1.</span> <span class="nav-text">前言</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#instancetype-classInfoWithClass-Class-cls"><span class="nav-number">1.1.</span> <span class="nav-text">+ (instancetype)classInfoWithClass:(Class)cls</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#void-update"><span class="nav-number">1.1.1.</span> <span class="nav-text">-(void)_update</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#第一部分"><span class="nav-number">1.1.1.1.</span> <span class="nav-text">第一部分</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#第二部分"><span class="nav-number">1.1.1.2.</span> <span class="nav-text">第二部分</span></a><ol class="nav-child"><li class="nav-item nav-level-6"><a class="nav-link" href="#part-one"><span class="nav-number">1.1.1.2.0.1.</span> <span class="nav-text">part one</span></a></li><li class="nav-item nav-level-6"><a class="nav-link" href="#part-two"><span class="nav-number">1.1.1.2.0.2.</span> <span class="nav-text">part two</span></a></li></ol></li></ol></li></ol></li></ol></li></ol></li></ol></div>
            
          </div>
        </section>
      

    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright" >
  
  &copy; 
  <span itemprop="copyrightYear">2016</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">Motom</span>
</div>

<div class="powered-by">
  由 <a class="theme-link" href="https://hexo.io">Hexo</a> 强力驱动
</div>

<div class="theme-info">
  主题 -
  <a class="theme-link" href="https://github.com/iissnan/hexo-theme-next">
    NexT.Muse
  </a>
</div>

        

        
      </div>
    </footer>

    <div class="back-to-top">
      <i class="fa fa-arrow-up"></i>
    </div>
  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>









  



  
  <script type="text/javascript" src="/vendors/jquery/index.js?v=2.1.3"></script>

  
  <script type="text/javascript" src="/vendors/fastclick/lib/fastclick.min.js?v=1.0.6"></script>

  
  <script type="text/javascript" src="/vendors/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>

  
  <script type="text/javascript" src="/vendors/velocity/velocity.min.js?v=1.2.1"></script>

  
  <script type="text/javascript" src="/vendors/velocity/velocity.ui.min.js?v=1.2.1"></script>

  
  <script type="text/javascript" src="/vendors/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script>


  


  <script type="text/javascript" src="/js/src/utils.js?v=5.0.1"></script>

  <script type="text/javascript" src="/js/src/motion.js?v=5.0.1"></script>



  
  

  
  <script type="text/javascript" src="/js/src/scrollspy.js?v=5.0.1"></script>
<script type="text/javascript" src="/js/src/post-details.js?v=5.0.1"></script>



  


  <script type="text/javascript" src="/js/src/bootstrap.js?v=5.0.1"></script>



  



  




  
  

  

  

  

</body>
</html>
